# @Version        : 1.0
# @Update Time    : 2024/9/10 21:35
# @File           : menu_schema.py
# @IDE            : PyCharm
# @Desc           : 文件描述信息
from typing import Optional, Literal, List, Union

from pydantic import Field, ConfigDict, BaseModel
from fastapi_utils.api_model import APIModel
from pydantic.alias_generators import to_camel

from src.core.base import BaseSchema
from src.schemas.base_schema import MixinSchema

from fastapi import Depends, Query
from src.core.dependencies import QueryParams, Paging


class MenuParams(QueryParams):
    def __init__(
        self,
        parent_id: int = Query(None, description="菜单ID", alias="parentId"),
        params: Paging = Depends(Paging),
    ):
        super().__init__(params)
        self.parent_id = parent_id


class MenuButtonSchema(BaseSchema):
    id: int | None = Field(None, description="按钮ID")
    status: Literal["1", "2"] = Field("1", description="是否启用1:启用，2:禁用")
    menu_id: int = Field(..., description="菜单ID")
    code: str = Field(..., max_length=64, description="按钮编码")
    desc: str = Field(..., max_length=64, description="按钮描述")


class MenuCreate(APIModel):
    status: Literal["1", "2"] = Field("1", description="是否启用1:启用，2:禁用")
    parent_id: int | None = Field(..., ge=0, description="父菜单ID")
    menu_type: str = Field(
        ..., max_length=1, description="菜单类型; 1:目录，2:菜单，3: 按钮"
    )
    menu_name: str = Field(..., max_length=64, description="菜单名称")
    route_name: Optional[str] = Field(None, max_length=64, description="路由名称")
    route_path: Optional[str] = Field(None, max_length=64, description="路由路径")
    component: Optional[str] = Field(None, max_length=64, description="组件路径")
    order: int = Field(..., ge=0, description="排序")
    i18n_key: Optional[str] = Field(None, max_length=64, description="国际化Key")
    icon: Optional[str] = Field(None, max_length=64, description="图标")
    icon_type: Optional[str] = Field(None, max_length=64, description="图标类型")

    path_param: Optional[str] = Field(None, max_length=200, description="路径参数")
    route_param: Optional[str] = Field(
        None, max_length=200, description="路由参数, List[dict]"
    )
    href: Optional[str] = Field(None, max_length=200, description="外链")
    multiple_tab: Optional[bool] = Field(False, description="是否支持多页签")
    keep_alive: bool = Field(False, description="是否缓存")
    hide_in_menu: bool = Field(False, description="是否在菜单隐藏")
    active_menu: Optional[str] = Field(
        None, max_length=100, description="隐藏的路由需要激活的菜单"
    )
    fixed_index_in_tab: Optional[int] = Field(
        None, ge=0, description="固定在页签的序号"
    )
    redirect: Optional[str] = Field(None, max_length=200, description="重定向路径")
    props: Optional[bool] = Field(False, description="是否为首路由")
    permissions: Optional[str] = Field(None, max_length=100, description="权限标识")
    constant: Optional[bool] = Field(False, description="是否为公共路由")


class MenuUpdate(MenuCreate):
    """
    菜单更新
    """

    id: int = Field(description="菜单ID")


class MenuList(MixinSchema, MenuCreate):
    buttons: Optional[List[MenuButtonSchema]] = Field(
        default=None, description="按钮列表"
    )


class MenuOut(MixinSchema, MenuCreate):
    """
    菜单输出
    """

    pass


class MenuInfo(MenuCreate):
    id: int = Field(description="菜单ID")


class MenuTree(MixinSchema, MenuCreate):
    children: Optional[List["MenuTree"]] = Field(default=None, description="子路由")


class MenuTreeOptions(APIModel):
    pId: int = Field(description="菜单ID")
    label: str = Field(description="菜单名称")
    value: str = Field(description="菜单ID")
    children: Optional[List["MenuTreeOptions"]] = Field(
        default=None, description="子路由"
    )


class MetaModel(BaseModel):
    title: Optional[str] = Field(
        default=None, description="设置路由在侧边栏和面包屑中展示的名字"
    )
    icon: Optional[str] = Field(default=None, description="设置路由的图标")
    no_cache: Optional[bool] = Field(
        default=None,
        description="设置为true，则不会被 <keep-alive>缓存",
        alias="noCache",
    )
    link: Optional[str] = Field(default=None, description="内链地址（http(s)://开头）")


class RouterModel(BaseModel):
    model_config = ConfigDict(alias_generator=to_camel)

    name: Optional[str] = Field(default=None, description="路由名称")
    path: Optional[str] = Field(default=None, description="路由地址")
    hidden: Optional[bool] = Field(
        default=None,
        description="是否隐藏路由，当设置 true 的时候该路由不会再侧边栏出现",
    )
    redirect: Optional[str] = Field(
        default=None,
        description="重定向地址，当设置 noRedirect 的时候该路由在面包屑导航中不可被点击",
    )
    component: Optional[str] = Field(default=None, description="组件地址")
    query: Optional[str] = Field(
        default=None, description='路由参数：如 {"id": 1, "name": "ry"}'
    )
    always_show: Optional[bool] = Field(
        default=None,
        description="当你一个路由下面的children声明的路由大于1个时，自动会变成嵌套的模式--如组件页面",
    )
    meta: Optional[MetaModel] = Field(default=None, description="其他元素")
    children: Optional[Union[List["RouterModel"], None]] = Field(
        default=None, description="子路由"
    )
